package com.dongdongshop.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.dongdongshop.data.DataResult;
import com.dongdongshop.data.ResponseStausEnum;
import com.dongdongshop.pojo.*;
import com.dongdongshop.service.*;
import com.dongdongshop.util.ShiroUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;


/**
 * @Description
 * @ClassName UserLoginController
 * @Author RC
 * @date 2020.12.18 21:10
 */
@Controller
@RequestMapping("user")
public class UserLoginController {

    @Reference(timeout = 10000,check = false)
    private UserService userService;
    @Reference(timeout = 10000,check = false)
    private AddRessService addRessService;
    @Reference(timeout = 10000,check = false)
    private CitiesService citiesService;
    @Reference(timeout = 10000,check = false)
    private AreaService areaService;
    @Reference(timeout = 10000,check = false)
    private UserScoreUseService userScoreUseService;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private RedisTemplate redisTemplate;
    public static final Logger logger = LoggerFactory.getLogger(UserLoginController.class);

    @RequestMapping("register")
    @ResponseBody
    public DataResult saveSeller(TbUser tbUser,String message){
        //保存  数据有空值 数据库保存异常 ,业务方面导致的没有添加成功 falise
        //可以使用map
        try{
            /*springbootReis序列化问题*/
            RedisSerializer stringSerializer = new StringRedisSerializer();
            redisTemplate.setKeySerializer(stringSerializer);
            redisTemplate.setValueSerializer(stringSerializer);
            redisTemplate.setHashKeySerializer(stringSerializer);
            redisTemplate.setHashValueSerializer(stringSerializer);
            //从redis缓存获取验证码
            ValueOperations ops = redisTemplate.opsForValue();
            String phone =(String) ops.get(tbUser.getPhone());
            //判断验证码
            if(message!=null && !"".equals(message) && message.equals(phone)){
                logger.info("进入用户注册方法");
                //先随机生成一个加密用的盐
                String salt = ShiroUtils.generateSalt(6);//随机生成一个我么指定长度的字符串
                tbUser.setSalt(salt);
                tbUser.setPassword(ShiroUtils.encryptPassword("MD5",tbUser.getPassword(),tbUser.getSalt(), 3));
                tbUser.setCreated(new Date());
                tbUser.setUpdated(new Date());
                userService.register(tbUser);
                return DataResult.response(ResponseStausEnum.SUSSCESS).setData(1);
            }
            return DataResult.response(ResponseStausEnum.INTERNAL_SERVER_ERROR).setData(2);
        } catch (Exception e) {
            logger.info("注册失败", e);
            return DataResult.response(ResponseStausEnum.INTERNAL_SERVER_ERROR).setData(3);

        }
    }

    @RequestMapping("login")
    public String login(String username, String password, Model model, HttpServletRequest request){
        //获取用户主体 subject
        Subject subject = SecurityUtils.getSubject();

        //将表单提交的账号和密码封装成token对象

        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
        //执行登录逻辑
        try {
            subject.login(token);
        }catch (UnknownAccountException e){
            //账号不存在提示
            model.addAttribute("message","账号不存在");
            return "login";
        }catch (IncorrectCredentialsException e){
            //密码错误提示
            model.addAttribute("message","密码错误");
            return "login";
        }
        TbUser tbUser =(TbUser)subject.getPrincipal();
        request.getSession().setAttribute("loginUser",tbUser);
        return "redirect:/";
    }

    //自定义页面 没认证跳转登录页
    @RequestMapping("toLogin")
    public String toLogin(){
        return "login";
    }


    @RequestMapping("unauthorized")
    public String unauthorized(){
        return "unauthorized";
    }

    //发送mq获取验证码
    @RequestMapping("sendMessage")
    @ResponseBody
    public DataResult sendMessage(String phone){
        //保存  数据有空值 数据库保存异常 ,业务方面导致的没有添加成功 falise
        //可以使用map
        try{
            logger.info("进入增加品牌方法");
            rocketMQTemplate.convertAndSend("phone",phone);

            return DataResult.response(ResponseStausEnum.SUSSCESS);
        } catch (Exception e) {
            logger.info("增加失败", e);
            return DataResult.response(ResponseStausEnum.INTERNAL_SERVER_ERROR);

        }
    }

    //地址管理
    @RequestMapping("showAddress")
    @ResponseBody
    public DataResult showAddress(){
        //保存  数据有空值 数据库保存异常 ,业务方面导致的没有添加成功 falise
        //可以使用map
        try{
            logger.info("进入查询方法");
            Subject subject = SecurityUtils.getSubject();
            TbUser user =(TbUser) subject.getPrincipal();
            List<AddressVO> addresses = addRessService.getAddressInfo(user.getUsername());
            return DataResult.response(ResponseStausEnum.INTERNAL_SERVER_ERROR).setData(addresses);
        } catch (Exception e) {
            logger.info("查询失败", e);
            return DataResult.response(ResponseStausEnum.INTERNAL_SERVER_ERROR);

        }
    }
    //根据省获取市
    @RequestMapping("updateThisCity")
    @ResponseBody
    public DataResult updateThisCity(Integer provinceid){
        //保存  数据有空值 数据库保存异常 ,业务方面导致的没有添加成功 falise
        //可以使用map
        try{
            logger.info("进入查询方法");
            List<TbCities> citiesList = citiesService.getCityListByProvinceId(provinceid);
            return DataResult.response(ResponseStausEnum.INTERNAL_SERVER_ERROR).setData(citiesList);
        } catch (Exception e) {
            logger.info("查询失败", e);
            return DataResult.response(ResponseStausEnum.INTERNAL_SERVER_ERROR);

        }
    }
    //根据市获取区县
    @RequestMapping("changeCity")
    @ResponseBody
    public DataResult changeCity(Integer cityid){
        //保存  数据有空值 数据库保存异常 ,业务方面导致的没有添加成功 falise
        //可以使用map
        try{
            logger.info("进入查询方法");
            List<TbAreas> areasList = areaService.getAreaListByCityId(cityid);
            return DataResult.response(ResponseStausEnum.INTERNAL_SERVER_ERROR).setData(areasList);
        } catch (Exception e) {
            logger.info("查询失败", e);
            return DataResult.response(ResponseStausEnum.INTERNAL_SERVER_ERROR);
        }
    }
    //保存
    @RequestMapping("saveAddRessInfo")
    @ResponseBody
    public DataResult saveAddRessInfo(TbAddress address){
        //保存  数据有空值 数据库保存异常 ,业务方面导致的没有添加成功 falise
        //可以使用map
        try{
            logger.info("进入保存");
            Subject subject = SecurityUtils.getSubject();
            TbUser user =(TbUser) subject.getPrincipal();
            address.setUserId(user.getUsername());
            addRessService.saveAddRessInfo(address);
            return DataResult.response(ResponseStausEnum.SUSSCESS);
        } catch (Exception e) {
            logger.info("保存失败", e);
            return DataResult.response(ResponseStausEnum.INTERNAL_SERVER_ERROR);
        }
    }

    //条件查询
    @RequestMapping("toUpdate")
    @ResponseBody
    public DataResult toUpdate(Long id){
        //保存  数据有空值 数据库保存异常 ,业务方面导致的没有添加成功 falise
        //可以使用map
        try{
            logger.info("进入条件查询");


            TbAddress address = addRessService.getInfoById(id);
            return DataResult.response(ResponseStausEnum.SUSSCESS).setData(address);
        } catch (Exception e) {
            logger.info("查询失败", e);
            return DataResult.response(ResponseStausEnum.INTERNAL_SERVER_ERROR);
        }
    }
    //修改
    @RequestMapping("updateAddRessInfo")
    @ResponseBody
    public DataResult updateAddRessInfo(TbAddress address){
        //保存  数据有空值 数据库保存异常 ,业务方面导致的没有添加成功 falise
        //可以使用map
        try{
            logger.info("进入修改");
            addRessService.updateAddRessInfo(address);
            return DataResult.response(ResponseStausEnum.SUSSCESS);
        } catch (Exception e) {
            logger.info("修改失败", e);
            return DataResult.response(ResponseStausEnum.INTERNAL_SERVER_ERROR);
        }
    }
    //删除
    @RequestMapping("deleteInfo")
    @ResponseBody
    public DataResult deleteInfo(Long id){
        //保存  数据有空值 数据库保存异常 ,业务方面导致的没有添加成功 falise
        //可以使用map
        try{
            logger.info("进入删除");

            addRessService.deleteInfo(id);
            return DataResult.response(ResponseStausEnum.SUSSCESS);
        } catch (Exception e) {
            logger.info("删除失败", e);
            return DataResult.response(ResponseStausEnum.INTERNAL_SERVER_ERROR);
        }
    }
    //积分兑换
    @RequestMapping("Points_exchange")
    @ResponseBody
    public DataResult Points_exchange(Integer score){
        //保存  数据有空值 数据库保存异常 ,业务方面导致的没有添加成功 falise
        //可以使用map
        try{
            logger.info("兑换积分");
            Subject subject = SecurityUtils.getSubject();
            TbUser user =(TbUser) subject.getPrincipal();
            //String code = "";
           // code = "300";
            //return DataResult.response(ResponseStausEnum.SUSSCESS).setData(code);
            String code = userScoreUseService.Points_exchange(score,user.getUsername());
            return DataResult.response(ResponseStausEnum.SUSSCESS).setData(code);
        } catch (Exception e) {
            logger.info("兑换失败", e);
            return DataResult.response(ResponseStausEnum.INTERNAL_SERVER_ERROR);
        }
    }



}
